package com.snake.util;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.TimeZone;

/**
 * 将字符串转换成日期 "2014-03-12 12:05:34", "2014-03-12 12:05", "2014-03-12 12",
 * "2014-03-12", "2014-03", "2014", "20140312120534", "2014/03/12 12:05:34",
 * "2014/3/12 12:5:34", "2014年3月12日 12时5分34秒", "201403121205", "2014031212",
 * "20140312", "201403", "12:05:34", "12:05",
 */
public class DateUtil {
	/** 
	 * 获取更改时区后的日期 
	 * @param date 日期 
	 * @param oldZone 旧时区对象 
	 * @param newZone 新时区对象 
	 * @return 日期 
	 */  
	public static Date changeTimeZone(Date date, TimeZone oldZone, TimeZone newZone) {  
	    Date dateTmp = null;  
	    if (date != null) {  
	        int timeOffset = oldZone.getRawOffset() - newZone.getRawOffset();  
	        dateTmp = new Date(date.getTime() - timeOffset);  
	    }  
	    return dateTmp;  
	} 
	// 按照给定的格式化字符串格式化日期
	public static String formatDate(Date date, String formatStr) {
		SimpleDateFormat sdf = new SimpleDateFormat(formatStr);
		return sdf.format(date);
	}

	// 按照给定的格式化字符串解析日期
	private static Date parseDate(String dateStr, String formatStr)
			throws ParseException {
		Date date = null;
		SimpleDateFormat sdf = new SimpleDateFormat(formatStr);
		date = sdf.parse(dateStr);
		return date;
	}

	// 从字符串中分析日期
	public static Date parseDate(String dateStr) throws ParseException {
		Date date = null;
		String[] dateArray = dateStr.split("\\D+"); // +防止多个非数字字符在一起时导致解析错误
		int dateLen = dateArray.length;
		int dateStrLen = dateStr.length();
		if (dateLen > 0) {
			if (dateLen == 1 && dateStrLen > 4) {
				if (dateStrLen == "yyyyMMddHHmmss".length()) {
					// 如果字符串长度为14位并且不包含其他非数字字符，则按照（yyyyMMddHHmmss）格式解析
					date = parseDate(dateStr, "yyyyMMddHHmmss");
				} else if (dateStrLen == "yyyyMMddHHmm".length()) {
					date = parseDate(dateStr, "yyyyMMddHHmm");
				} else if (dateStrLen == "yyyyMMddHH".length()) {
					date = parseDate(dateStr, "yyyyMMddHH");
				} else if (dateStrLen == "yyyyMMdd".length()) {
					date = parseDate(dateStr, "yyyyMMdd");
				} else if (dateStrLen == "yyyyMM".length()) {
					date = parseDate(dateStr, "yyyyMM");
				}
			} else {
				String fDateStr = dateArray[0];
				for (int i = 1; i < dateLen; i++) {
					// 左补齐是防止十位数省略的情况
					fDateStr += leftPad(dateArray[i], "0", 2);
				}

				if (dateStr.trim().matches("^\\d{1,2}:\\d{1,2}(:\\d{1,2})?$")) {
					// 补充年月日3个字段
					dateLen += 3;
					fDateStr = formatDate(new Date(), "yyyyMMdd") + fDateStr;
				}

				date = parseDate(fDateStr,
						"yyyyMMddHHmmss".substring(0, (dateLen - 1) * 2 + 4));
			}
		}

		return date;
	}

	// 左补齐
	private static String leftPad(String str, String pad, int len) {
		String newStr = (str == null ? "" : str);
		while (newStr.length() < len) {
			newStr = pad + newStr;
		}
		if (newStr.length() > len) {
			newStr = newStr.substring(newStr.length() - len);
		}
		return newStr;
	}

	/*
	 * public static void main(String[] args) throws ParseException {
	 * 
	 * String[] dateStrArray=new String[]{ "2014-03-12 12:05:34",
	 * "2014-03-12 12:05", "2014-03-12 12", "2014-03-12", "2014-03", "2014",
	 * "20140312120534", "2014/03/12 12:05:34", "2014/3/12 12:5:34",
	 * "2014年3月12日 12时5分34秒", "201403121205", "2014031212", "20140312",
	 * "201403", "12:05:34", "12:05", }; for(int i=0;i<dateStrArray.length;i++){
	 * Date date=parseDate(dateStrArray[i]);
	 * System.out.println(dateStrArray[i]+" ==> "
	 * +formatDate(date,"yyyy-MM-dd HH:mm:ss")); } }
	 */

	// 获取某一月中有多少天
	public int getDayNumber(String strDate) {
		// String strDate = "2012-02";
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
		Calendar calendar = new GregorianCalendar();
		Date date1 = null;
		try {
			date1 = sdf.parse(strDate);
			calendar.setTime(date1); // 放入你的日期
			int actualMaximum = calendar
					.getActualMaximum(Calendar.DAY_OF_MONTH);
			return actualMaximum;
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return 0;

	}

	/**
	 * 根据开始时间和结束时间返回时间段内的时间集合
	 * 
	 * @param beginDate
	 * @param endDate
	 * @return List
	 */
	public static List<Date> getDatesBetweenTwoDate(Date beginDate, Date endDate) {
		List<Date> lDate = new ArrayList<Date>();
		lDate.add(beginDate);// 把开始时间加入集合
		Calendar cal = Calendar.getInstance();
		// 使用给定的 Date 设置此 Calendar 的时间
		cal.setTime(beginDate);
		boolean bContinue = true;
		while (bContinue) {
			// 根据日历的规则，为给定的日历字段添加或减去指定的时间量
			cal.add(Calendar.DAY_OF_MONTH, 1);
			// 测试此日期是否在指定日期之后
			if (endDate.after(cal.getTime())) {
				lDate.add(cal.getTime());
			} else {
				break;
			}
		}
		lDate.add(endDate);// 把结束时间加入集合
		return lDate;
	}

	/**
	 * 两个时间之间相差距离多少天
	 * 
	 * @param one
	 *            时间参数 1：
	 * @param two
	 *            时间参数 2：
	 * @return 相差天数
	 */
	public static long getDistanceDays(String str1, String str2)
			throws Exception {
		DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
		Date one;
		Date two;
		long days = 0;
		try {
			one = df.parse(str1);
			two = df.parse(str2);
			long time1 = one.getTime();
			long time2 = two.getTime();
			long diff;
			if (time1 < time2) {
				diff = time2 - time1;
			} else {
				diff = time1 - time2;
			}
			days = diff / (1000 * 60 * 60 * 24);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return days;
	}

	/**
	 * 判断日期是否在一个日期范围内
	 * 
	 * @param startDate
	 *            开始日期：
	 * @param endDate
	 *            结束日期：
	 * @param date
	 *            要判断的日期
	 * @return true：在范围内，false不在范围内
	 */
	public static boolean isServiceOut(String startDate, String endDate,
			String date) throws Exception {
		long startDa = getTimess(startDate);
		long endDa = getTimess(endDate);
		long da = getTimess(date);
		if(da>=startDa&&da<=endDa){
			return true;
		}else{
			return false;
		}
	}
	/**
	 * 判断日期是否在开始日期之外
	 * 
	 * @param startDate
	 *            开始日期：
	 * @param date
	 *            要判断的日期
	 * @return true：在范围内，false不在范围内
	 */
	public static boolean isStartDateOut(String startDate,
			String date) throws Exception {
		long startDa = getTimess(startDate);
		long da = getTimess(date);
		if(da>=startDa){
			return true;
		}else{
			return false;
		}
	}
	/**
	 * 判断日期是否在结束日期之外
	 * 
	 * @param startDate
	 *            开始日期：
	 * @param date
	 *            要判断的日期
	 * @return true：在范围内，false不在范围内
	 */
	public static boolean isEndDateOut(String endDate,
			String date) throws Exception {
		long endDa = getTimess(endDate);
		long da = getTimess(date);
		if(da<=endDa){
			return true;
		}else{
			return false;
		}
	}
	//将日期转换成时间戳
	public static long getTimess(String user_time) throws ParseException {
		SimpleDateFormat simpleDateFormat =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	     Date startDa=simpleDateFormat.parse(user_time);
	     long time = startDa.getTime();
	     return time;
	}
}
